﻿using Flatland.GeneticProgramming.CoreTypes;
using Flatland.GeneticProgramming.SyntaxTree;

namespace Flatland.GeneticProgramming.Initializations {

    /// <summary>
    /// Initialization strategy. Add a new GP technique by defining an enum and provide the implementer of IInitialization 
    /// </summary>
    public enum InitializationTechnique {
        [GPTechnique(typeof(FullInitialization))]
        Full,

        [GPTechnique(typeof(GrowInitialization))]
        Grow,

        [GPTechnique(typeof(RampedHalfAndHalf))]
        RampedHalfAndHalf

    }

    public class Initialization : IInitialization {

        /// <summary>
        /// IInitialization implementation.
        /// </summary>
        private IInitialization _initialization;

        /// <summary>
        /// Constructor.
        /// </summary>
        public Initialization(InitializationTechnique initTechnique) {
            _initialization = (IInitialization)GPTechnique.GetImplementer(typeof(InitializationTechnique), (int)initTechnique);
        }

        public Tree Init(uint maxDepth, PrimitiveSet primitiveSet) {
            return _initialization.Init(maxDepth, primitiveSet);
        }
    }
}
